package com.dreammore.framework.common.dao;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class CommonDAO implements ICommonDAO {
	
	private SessionFactory sessionFactory;  
	  
    public void setSessionFactory(SessionFactory sessionFactory) {  
        this.sessionFactory = sessionFactory;  
    }  
    
    public Session getSession() {  
        return sessionFactory.getCurrentSession();  
    }  

	@Override
	public void clear() {
		getSession().clear();
	
	}

	@Override
	public <T> void delete(T obj) {
		getSession().delete(obj);
	}
	
	@Override
	public <T> void merge(T obj) {
		getSession().merge(obj);
	}

	@Override
	public void deleteAll(String hql, Object... values) {
		Query query = getSession().createQuery(hql);
		for (int i = 0; i < values.length; i++) {
			query.setParameter(i, values[i]);
		}
		query.executeUpdate();
	}
	
	@Override
	public void deleteAll(String hql, String[] paramNames, Object[] values) {
	
		Query query = getSession().createQuery(hql);
		if (paramNames != null) {
			for (int i = 0; i < paramNames.length; i++){
				if (values[i] instanceof List ) {
					query.setParameterList(paramNames[i], (List) values[i]);
				}else if(values[i] instanceof Object[]) {
					query.setParameterList(paramNames[i], (Object[]) values[i]);
				}else {
					query.setParameter(paramNames[i], values[i]);
				}
			}
		}else {
			for (int i = 0; i < values.length; i++) {
				query.setParameter(i, values[i]);
			}
		}
		query.executeUpdate();
	}

	@Override
	public void evict(Object obj) {
		getSession().evict(obj);
	}

	@Override
	public <T> void evictList(List<T> list) {
		for (Object object : list) {
			evict(object);
		}
	}

	@Override
	public void executeHQL(String hql, Object[] values) {

		Session session = getSession();
		Query query = session.createQuery(hql);
		if (values != null) {
			for (int i = 0; i < values.length; i++){
				query.setParameter(i, values[i]);
			}
		}
		query.executeUpdate();
		
	}
	
	

	@Override
	public void executeHQL(String hql, String[] paramNames, Object[] values) {
		Session session = getSession();
		Query query = session.createQuery(hql);
		if (paramNames != null) {
			for (int i = 0; i < paramNames.length; i++){
				if (values[i] instanceof List ) {
					query.setParameterList(paramNames[i], (List) values[i]);
				}else if(values[i] instanceof Object[]) {
					query.setParameterList(paramNames[i], (Object[]) values[i]);
				}else {
					query.setParameter(paramNames[i], values[i]);
				}
			}
		}else {
			for (int i = 0; i < values.length; i++) {
				query.setParameter(i, values[i]);
			}
		}
		query.executeUpdate();
		
	}

	@Override
	public void executeSQL(String sql, Object[] params) {
		Query query = getSession().createSQLQuery(sql);
		if (params != null) {
			for (int i = 0; i < params.length; i++){
				query.setParameter(i, params[i]);
			}
		}
		query.executeUpdate();
		
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Object[]> findBySQL(String sql, Object[] values) {
		Session session = getSession();
		Query query = session.createSQLQuery(sql);
		if (values != null) {
			for (int i = 0; i < values.length; i++){
				query.setParameter(i, values[i]);
			}
		}
		List<Object[]> result = query.list();
		return result;
	}
	
	
	@Override
	public List<Object[]> executeFindBySQL(String[] preSqls, String sql,	Object[] params) {
		Session session = getSession();
		Query query = null;
		if (preSqls != null) {
			for (String preSql : preSqls) {
				query = session.createSQLQuery(preSql);
				query.executeUpdate();
			}
		}
		
		query = session.createSQLQuery(sql);
		if (params != null) {
			for (int i = 0; i < params.length; i++){
				query.setParameter(i, params[i]);
			}
		}
		@SuppressWarnings("unchecked")
		List<Object[]> result = query.list();
		return result;
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> findBySQL(String sql, Object[] params, Class<T> entity) {
		Session session = getSession();
		
		Query query = session.createSQLQuery(sql).addEntity(entity);
		if (params != null) {
			for (int i = 0; i < params.length; i++)
				query.setParameter(i, params[i]);
		}
		List<T> result = query.list();
		
		return result;
	}

	@Override
	public void findBySQL(String sql, @SuppressWarnings("rawtypes") PageBean pageBean) {
		QueryPage queryPage = new QueryPage(sql, pageBean, true);
		queryPage.doInHibernate(getSession());
	}
	
	@Override
	public void findBySQL(String sql,  Object[] params, @SuppressWarnings("rawtypes") PageBean pageBean) {
		QueryPage queryPage = new QueryPage(sql, params, pageBean, true);
		queryPage.doInHibernate(getSession());
	}


	@SuppressWarnings("unchecked")
	@Override
	public <T> List<T> find(String hql) {
		Query query = getSession().createQuery(hql);
		return query.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> List<T> find(String hql, Object... values) {
		Query query = getSession().createQuery(hql);
		for (int i = 0; i < values.length; i++) {  
			query.setParameter(i, values[i]);
        } 
		return query.list();
	}

	@Override
	public void find(String hql, @SuppressWarnings("rawtypes") PageBean pageObj, Object... values) {
		QueryPage queryPage = new QueryPage(hql, pageObj, values);
		queryPage.doInHibernate(getSession());
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> List<T> find(String hql, String[] paramNames, Object[] values) {
		Query selectQuery = getSession().createQuery(hql);
		if(values!= null){
			for (int i = 0; i < values.length; i++) {

				if(values[i] instanceof List){
					selectQuery.setParameterList(paramNames[i],(List)values[i]);
				}else if (values[i] instanceof Object[]) {
					selectQuery.setParameterList(paramNames[i],(Object[])values[i]);
				}else{
					if(paramNames==null){
						selectQuery.setParameter(i,values[i]);
					}else{
						selectQuery.setParameter(paramNames[i],values[i]);
					}
				}
			}
		}
		return selectQuery.list();
	}

	@Override
	public void find(String hql, @SuppressWarnings("rawtypes") PageBean pageObj, String[] paramNames, Object[] values) {
		QueryPage queryPage = new QueryPage(hql, pageObj, values, paramNames);
		queryPage.doInHibernate(getSession());
		
	}
	
	

	@SuppressWarnings("unchecked")
	@Override
	public <T> List<T> findTop(String hql, int topNum, Object... values) {
		Query selectQuery = getSession().createQuery(hql);
		if(values!= null){
			for (int i = 0; i < values.length; i++) {
				selectQuery.setParameter(i, values[i]);
			}
		}
		selectQuery.setMaxResults(topNum);
		
		return selectQuery.list();
	}

	@Override
	public void flush() {
		getSession().flush();
	}

	@Override
	public <T> T get(Class<T> entityClass, Serializable id) {
		return (T) getSession().get(entityClass, id);
	}

	


	@Override
	public <T> T load(Class<T> entityClass, Serializable id) {
		return (T) getSession().load(entityClass, id);
	}

	@Override
	public <T> void refresh(T obj) {
		getSession().refresh(obj);
	}

	@Override
	public <T> void save(T obj) {
		getSession().save(obj);
	}

	@Override
	public <T> void update(T obj) {
		getSession().update(obj);
	}

	@Override
	public <T> void saveOrupdate(T obj) {
		getSession().saveOrUpdate(obj);
	}

	
}
